package querydatabaseselection.selector;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;

import distributedRE.model.DataBase;
import distributedRE.model.DistributedREModel;
import distributedRE.model.Query;
import distributedRE.model.QueryDatabase;

import querydatabaseselection.pair.QueryDatabasePair;


public class UpToMDatabases extends QueryDatabaseSelector {

	private long M;

	public UpToMDatabases(long M){
		this.M = M;
	}
	
	@Override
	protected boolean isDescending() {
		return true;
	}

	@Override
	protected List<QueryDatabasePair> select(
			ArrayList<QueryDatabasePair> calculatedValues, DistributedREModel dREModel) {
		
		ArrayList<QueryDatabasePair> ret = new ArrayList<QueryDatabasePair>();
		
		Hashtable<Long, Integer> ht = new Hashtable<Long, Integer>();
		
		HashSet<DataBase> alreadyAdded = new HashSet<DataBase>();
		
		for (QueryDatabasePair queryDatabasePair : calculatedValues) {
		
			DataBase db = queryDatabasePair.getDatabase();
			
			QueryDatabase qdb = QueryDatabase.getInstance(queryDatabasePair.getQuery(), db, dREModel);
			
			if (qdb.isSelectable()){
				
				Integer pt = ht.get(new Long(db.getId()));
				
				if (pt==null){
					pt = new Integer(0);
				}
				
				pt = new Integer(pt.intValue()+1);
				
				ht.put(new Long(db.getId()), pt);
				
				alreadyAdded.add(db);
				
				if (alreadyAdded.size()>M){
					return ret;
				}
				else{
					if (pt.intValue() <= db.getConcurrentQueriesNumber()){
						
						ret.add(queryDatabasePair);
						
					}
				}
					
				
			}
			
		}
		
		return ret;
		
	}

}
